package mv.releaser.model;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class AviInputFile {

	private File		f;

	/**
	 * avi headers see http://www.opennet.ru/docs/formats/avi.txt for more
	 * informations
	 */
	final private int[]	aviHeader;

	final private int[]	streamHeader;

	public AviInputFile(String path) throws IOException {
		f = new File(path);
		aviHeader = new int[14];
		streamHeader = new int[14];
		getHeaders();
	}

	public AviInputFile(File f) throws IOException, NotAnAviFileException {
		this.f = f;
		aviHeader = new int[14];
		streamHeader = new int[14];
		checkHeaders();
		getHeaders();
	}

	private void getHeaders() throws IOException {
		RandomAccessFile raf = new RandomAccessFile(f, "r");
		byte b[] = new byte[4];
		int chunk;

		raf.seek(32);
		for (int i = 0; i < aviHeader.length; i++) {
			raf.read(b);
			chunk = b[0] & 0xFF;
			chunk |= (b[0 + 1] & 0xFF) << 8;
			chunk |= (b[0 + 2] & 0xFF) << 16;
			chunk |= (b[0 + 3] & 0xFF) << 24;
			aviHeader[i] = chunk;
		}

		raf.seek(108);
		for (int i = 0; i < streamHeader.length; i++) {
			raf.read(b);
			chunk = b[0] & 0xFF;
			chunk |= (b[0 + 1] & 0xFF) << 8;
			chunk |= (b[0 + 2] & 0xFF) << 16;
			chunk |= (b[0 + 3] & 0xFF) << 24;
			streamHeader[i] = chunk;
		}

		raf.close();
	}

	public double getFrameRate() {
		return (double) streamHeader[6] / streamHeader[5];
	}

	public int getMinutes() {
		double duration = getTotalFrame() / getFrameRate();
		return (int) duration / 60;
	}

	public int getSeconds() {
		double duration = getTotalFrame() / getFrameRate();
		return (int) (duration - ((int) duration / 60) * 60);
	}

	public int getWidth() {
		return aviHeader[8];
	}

	public int getHeight() {
		return aviHeader[9];
	}

	public int getTotalFrame() {
		return aviHeader[4];
	}

	public int getTotalStream() {
		return aviHeader[6];
	}

	public String getFilePath() {
		return f.getAbsolutePath();
	}

	public long getCRC() throws IOException {
		final CRC crc = new CRC(f);
		return crc.getCRC();
	}

	private void checkHeaders() throws NotAnAviFileException, IOException {
		RandomAccessFile fin = new RandomAccessFile(f, "r");

		String fourCC = "";
		for (int i = 0; i < 4; i++)
			fourCC += (char) fin.read();

		// check if its a correct riff file
		if (!fourCC.equals("RIFF")) {
			fin.close();
			throw new NotAnAviFileException(f.getAbsolutePath()
					+ " is not a valid AVI file.");
		}

		// check the form type of the data chunck, which begin at byte 8
		fin.seek(8);
		fourCC = "";
		for (int i = 0; i < 4; i++)
			fourCC += (char) fin.read();

		if (!fourCC.startsWith("AVI")) {
			fin.close();
			throw new NotAnAviFileException(f.getAbsolutePath()
					+ " is not a valid AVI file.");
		}
		
		fin.close();

	}

	public boolean renameTo(File dest) {
		return f.renameTo(dest);
	}
}
